<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="Cask Data, Inc." name="author" />
<meta content="Copyright © 2014-2017 Cask Data, Inc." name="copyright" />


    <meta name="git_release" content="6.1.1">
    <meta name="git_hash" content="05fbac36f9f7aadeb44f5728cea35136dbc243e5">
    <meta name="git_timestamp" content="2020-02-09 08:22:47 +0800">
    <title>Debugging a CDAP Application</title>

    <link rel="stylesheet" href="../_static/cdap-bootstrap.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootstrap-3.3.6/css/bootstrap.min.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/cdap-dynamicscrollspy-4.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/cdap-jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../_static/css/abixTreeList-2.css" type="text/css" />
    <link rel="stylesheet" href="../_static/cdap-bootstrap.css" type="text/css" />

    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '6.1.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  false
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>

    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="top" title="Cask Data Application Platform 6.1.1 Documentation" href="../index.html" />
    <link rel="up" title="Testing and Debugging" href="index.html" />
    <link rel="next" title="Troubleshooting a CDAP Application" href="troubleshooting.html" />
    <link rel="prev" title="Testing a CDAP Application" href="testing.html" />
    <!-- block extrahead -->
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <!-- block extrahead end -->

</head>
<body role="document">

<!-- block navbar -->
<div id="navbar" class="navbar navbar-inverse navbar-default navbar-fixed-top">
    <div class="container-fluid">
      <div class="row">
        <div class="navbar-header">
          <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
          <a class="navbar-brand" href="../table-of-contents/../../index.html">
            <span><img alt="CDAP logo" src="../_static/cdap_logo.svg"/></span>
          </a>

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>

          <div class="pull-right">
            <div class="dropdown version-dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                role="button" aria-haspopup="true" aria-expanded="false">
                v 6.1.1 <span class="caret"></span>
              </a>
              <ul class="dropdown-menu">
                <li><a href="//docs.cdap.io/cdap/5.1.2/en/index.html">v 5.1.2</a></li>
                <li><a href="//docs.cdap.io/cdap/4.3.4/en/index.html">v 4.3.4</a></li>
              </ul>
            </div>
          </div>
          <form class="navbar-form navbar-right navbar-search" action="../search.html" method="get">
            <div class="form-group">
              <div class="navbar-search-image material-icons"></div>
              <input type="text" name="q" class="form-control" placeholder="  Search" />
            </div>
            <input type="hidden" name="check_keywords" value="yes" />
            <input type="hidden" name="area" value="default" />
          </form>

          <div class="collapse navbar-collapse nav-collapse navbar-right navbar-navigation">
            <ul class="nav navbar-nav"><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../index.html">简介</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link current" href="../table-of-contents/../../guides.html">手册</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../reference-manual/index.html">参考</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../table-of-contents/../../faqs/index.html">帮助</a></li>
            </ul>
          </div>

        </div>
      </div>
    </div>
  </div><!-- block navbar end -->
<!-- block main content -->
<div class="main-container container">
  <div class="row"><div class="col-md-2">
      <div id="sidebar" class="bs-sidenav scrollable-y-outside" role="complementary">
<!-- theme_manual: developer-manual -->
<!-- theme_manual_highlight: guides -->
<!-- sidebar_title_link: ../table-of-contents/../../guides.html -->

  <div role="note" aria-label="manuals links"><h3><a href="../table-of-contents/../../guides.html">Guides</a></h3>

    <ul class="this-page-menu">
      <li class="toctree-l1"><a href="../table-of-contents/../../user-guide/index.html" rel="nofollow">用户手册</a>
      </li>
      <li class="toctree-l1"><b><a href="../table-of-contents/../../developer-manual/index.html" rel="nofollow">开发手册</a></b>
      <nav class="pagenav">
      <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html"> 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../getting-started/index.html"> 入门指南</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/sandbox/index.html">CDAP Sandbox</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/zip.html">二进制 Zip 文件</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/zip.html#cdap-sandbox">启动和停止 CDAP Sandbox</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/virtual-machine.html">虚拟机镜像</a></li>
<li class="toctree-l3"><a class="reference internal" href="../getting-started/sandbox/docker.html">Docker 镜像</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/quick-start.html">快速入门</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/dev-env.html">搭建开发环境</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/start-stop-cdap.html">启动和停止 CDAP</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started/building-apps.html">构建并运行应用</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../overview/index.html"> 概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../overview/anatomy.html"> 大数据应用剖析</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/modes.html"> 模式和组件</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/abstractions.html"> 核心概念</a></li>
<li class="toctree-l2"><a class="reference internal" href="../overview/interfaces.html"> 编程接口</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../building-blocks/index.html"> 抽象概念</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/core.html"> Core Abstractions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/applications.html"> Applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/datasets/index.html"> Datasets</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/overview.html"> Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/table.html"> Table API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/fileset.html"> FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/partitioned-fileset.html"> Partitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/time-partitioned-fileset.html"> TimePartitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/system-custom.html"> System and Custom Datasets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/permissions.html"> Dataset Permissions</a></li>
<li class="toctree-l3"><a class="reference internal" href="../building-blocks/datasets/cube.html"> Cube Dataset</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/mapreduce-programs.html"> MapReduce Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/plugins.html"> Plugins</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/schedules.html"> Schedules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/secure-keys.html"> Secure Keys</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/services.html"> Services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/spark-programs.html"> Spark Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/workers.html"> Workers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/workflows.html"> Workflows</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/artifacts.html"> Artifacts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/program-lifecycle.html"> Program Lifecycle</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/namespaces.html"> Namespaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/transaction-system.html"> Transaction System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../building-blocks/transactional-messaging-system.html"> Transactional Messaging System</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../metadata/index.html"> 元数据</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../metadata/system-metadata.html"> System Metadata</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/discovery-lineage.html"> Discovery and Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/field-lineage.html"> Field Level Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/audit-logging.html"> Audit Logging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/metadata-ui.html"> CDAP Metadata UI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../metadata/programmatic-metadata.html"> Accessing metadata programmatically</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../pipelines/index.html"> 数据流管道</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/concepts-design.html"> Concepts and Design</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/getting-started.html"> Getting Started</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/studio.html"> CDAP Studio</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/creating-pipelines.html"> Creating Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/running-pipelines.html"> Running Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/plugin-management.html"> Plugin Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/plugins/index.html"> Plugin Reference</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/actions/index.html"> Action Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/sources/index.html"> Source Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/transforms/index.html"> Transform Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/analytics/index.html"> Analytic Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/sinks/index.html"> Sink Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/shared-plugins/index.html"> Shared Plugins</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../pipelines/plugins/shared-plugins/core.html">CoreValidator</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/plugins/post-run-plugins/index.html"> Post-run Plugins</a><ul class="simple">
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/developing-pipelines.html"> Developing Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/developing-plugins/index.html"> Developing Plugins</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/plugin-basics.html">Plugin Basics</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/creating-a-plugin.html">Creating a Plugin</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/presentation-plugins.html">Plugin Presentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/testing-plugins.html">Testing Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pipelines/developing-plugins/packaging-plugins.html">Packaging Plugins</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../pipelines/how-cdap-pipelines-work.html"> How CDAP Pipelines Work</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../cloud-runtimes/index.html"> 云平台运行</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/concepts/index.html"> Concepts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/provisioners/index.html"> Provisioners</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/gcp-dataproc.html">Google Dataproc</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/aws-emr.html">Amazon Elastic MapReduce</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/provisioners/remote-hadoop.html">Remote Hadoop</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/profiles/index.html"> Profiles</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/creating-profiles.html">Creating Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/assigning-profiles.html">Assigning Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cloud-runtimes/profiles/admin-controls.html">Admin Controls</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-runtimes/example/index.html"> Example</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../security/index.html"> 安全</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../security/client-authentication.html">Client Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/cdap-authentication-clients-java.html">CDAP Authentication Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/cdap-authentication-clients-python.html">CDAP Authentication Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/custom-authentication.html">Custom Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../security/authorization-extensions.html">Authorization Extensions</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html"> 测试和调试</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="testing.html"> Testing a CDAP Application</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"> Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="troubleshooting.html"> Troubleshooting</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../ingesting-tools/index.html"> 数据融合</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-java.html">CDAP Stream Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-python.html">CDAP Stream Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-stream-clients-ruby.html">CDAP Stream Client for Ruby</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ingesting-tools/cdap-flume.html">CDAP Flume</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../data-exploration/index.html"> 数据探索</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/filesets.html"> Fileset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/tables.html"> Table Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/object-mapped-tables.html"> ObjectMappedTable Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/custom-datasets.html"> Custom Dataset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../data-exploration/hive-execution-engines.html"> Hive Execution Engines</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../advanced/index.html"> 高级主题</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../advanced/application-logback.html"> Application Logback</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/best-practices.html"> Best Practices</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/class-loading.html"> Class Loading</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/configuring-resources.html"> Configuring Program Resources</a></li>
<li class="toctree-l2"><a class="reference internal" href="../advanced/program-retry-policies.html"> Program Retry Policies</a></li>
</ul>
</li>
</ul>
</nav>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../admin-manual/index.html" rel="nofollow">管理手册</a>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../integrations/index.html" rel="nofollow">集成手册</a>
      </li>
      <li class="toctree-l1"><a href="../table-of-contents/../../examples-manual/index.html" rel="nofollow">最佳实践</a>
      </li>
    </ul>
  </div></div>
    </div><div class="col-md-8 content" id="main-content">
    
  <div class="section" id="debugging-a-cdap-application">
<span id="debugging-cdap"></span><h1>Debugging a CDAP Application<a class="headerlink" href="#debugging-a-cdap-application" title="Permalink to this headline">🔗</a></h1>
<div class="section" id="debugging-an-application-in-cdap-sandbox">
<span id="debugging-sandbox"></span><h2>Debugging an Application in CDAP Sandbox<a class="headerlink" href="#debugging-an-application-in-cdap-sandbox" title="Permalink to this headline">🔗</a></h2>
<p>Any CDAP application can be debugged in the CDAP Sandbox
by attaching a remote debugger to the CDAP JVM. To enable remote
debugging:</p>
<ol class="arabic">
<li><p class="first">Start the CDAP Sandbox with <code class="docutils literal notranslate"><span class="pre">--enable-debug</span></code>, optionally specifying a port (default is <code class="docutils literal notranslate"><span class="pre">5005</span></code>).</p>
<p>The CDAP should confirm that the debugger port is open with a message such as
<code class="docutils literal notranslate"><span class="pre">Remote</span> <span class="pre">debugger</span> <span class="pre">agent</span> <span class="pre">started</span> <span class="pre">on</span> <span class="pre">port</span> <span class="pre">5005</span></code>.</p>
</li>
<li><p class="first">Deploy (for example) the <em>SportResults</em> application to the CDAP by dragging and dropping the
<code class="docutils literal notranslate"><span class="pre">SportResults.jar</span></code> file from the <code class="docutils literal notranslate"><span class="pre">/examples/SportResults</span></code> directory onto the CDAP UI.</p>
</li>
<li><p class="first">Open the <em>SportResults</em> application in an IDE and connect to the remote debugger.</p>
</li>
</ol>
<p>For more information, see <a class="reference internal" href="#attaching-a-debugger">Attaching a Debugger</a>.</p>
<p><strong>Note:</strong> Currently, debugging is not supported under Windows.</p>
</div>
<div class="section" id="debugging-an-application-in-distributed-cdap">
<span id="debugging-distributed"></span><h2>Debugging an Application in Distributed CDAP<a class="headerlink" href="#debugging-an-application-in-distributed-cdap" title="Permalink to this headline">🔗</a></h2>
<p>In distributed mode, an application does not run in a single JVM. Instead, its programs
are dispersed over multiple—if not many—containers in the Hadoop cluster. There is no
single place to debug the entire application.</p>
<p>You can, however, debug every individual container by attaching a remote debugger to it.
This is supported for each flowlet of a flow and each instance of a service. In order
to debug a container, you need to start the component with debugging enabled by making
an HTTP request to the component’s URL. For example, the following will start a flow for debugging:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">POST /v3/namespaces/default/apps/WordCount/flows/WordCounter/debug</span>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">curl</span></code>:</p>

<script type="text/javascript">

  $(function tabbedparsedliteral71() {
    var tabs = ['linux', 'windows'];
    var mapping = {'windows': 'windows', 'linux': 'linux'};
    var tabSetID = 'linux-windows';
    for (var i = 0; i < tabs.length; i++) {
      var tab = tabs[i];
      $("#tabbedparsedliteral71 .example-tab-" + tab).click(changeExampleTab(tab, mapping, "tabbedparsedliteral71", tabSetID));
    }
  });

</script>
<div id="tabbedparsedliteral71" class="tabbed-parsed-literal dependent-linux-windows">
<ul class="tabbed-parsed-literal nav-tabs">
<li class="example-tab example-tab-linux active"><a href="#">Linux</a></li>
<li class="example-tab example-tab-windows "><a href="#">Windows</a></li>
</ul>

<div class="tab-contents">

<div class="tab-pane tab-pane-linux active">
<div class="code code-tab">
<div class="highlight-console">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">$</span> curl -w<span class="s2">&quot;\n&quot;</span> -X POST <span class="s2">&quot;http://&lt;hostname&gt;:11015/v3/namespaces/default/apps/WordCount/flows/WordCounter/debug&quot;</span>
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
<div class="tab-pane tab-pane-windows ">
<div class="code code-tab">
<div class="highlight-shell-session">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">&gt;</span> curl -X POST <span class="s2">&quot;http://&lt;hostname&gt;:11015/v3/namespaces/default/apps/WordCount/flows/WordCounter/debug&quot;</span>
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
</div>
</div>
<p>Note that this URL differs from the URL for starting the flow only by the last path
component (<code class="docutils literal notranslate"><span class="pre">debug</span></code> instead of <code class="docutils literal notranslate"><span class="pre">start</span></code>; see the <span class="xref std std-ref">http-restful-api-lifecycle</span>).
You can pass in runtime arguments in the exact same way as you normally would start a flow.</p>
<p>Once the flow is running, each flowlet will detect an available port in its container
and open that port for attaching a debugger.
To find out the address of a container’s host and the container’s debug port, you can query
the CDAP for a flow or service’s live info via HTTP:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">GET /v3/namespaces/default/apps/WordCount/flows/WordCounter/live-info</span>
</pre></div>
</div>
<p>or, using the CDAP CLI:</p>

<script type="text/javascript">

  $(function tabbedparsedliteral72() {
    var tabs = ['linux', 'windows'];
    var mapping = {'windows': 'windows', 'linux': 'linux'};
    var tabSetID = 'linux-windows';
    for (var i = 0; i < tabs.length; i++) {
      var tab = tabs[i];
      $("#tabbedparsedliteral72 .example-tab-" + tab).click(changeExampleTab(tab, mapping, "tabbedparsedliteral72", tabSetID));
    }
  });

</script>
<div id="tabbedparsedliteral72" class="tabbed-parsed-literal dependent-linux-windows">
<ul class="tabbed-parsed-literal nav-tabs">
<li class="example-tab example-tab-linux active"><a href="#">Linux</a></li>
<li class="example-tab example-tab-windows "><a href="#">Windows</a></li>
</ul>

<div class="tab-contents">

<div class="tab-pane tab-pane-linux active">
<div class="code code-tab">
<div class="highlight-console">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">$</span> cdap cli get flow live WordCount.WordCounter
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
<div class="tab-pane tab-pane-windows ">
<div class="code code-tab">
<div class="highlight-shell-session">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">&gt;</span> cdap cli get flow live WordCount.WordCounter
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
</div>
</div>
<p>The response is formatted in JSON and—pretty-printed— would look similar to this:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">{</span>
<span class="go">  &quot;app&quot;: &quot;WordCount&quot;,</span>
<span class="go">  &quot;containers&quot;: [</span>
<span class="go">    {</span>
<span class="go">      &quot;container&quot;: &quot;container_1397069870124_0010_01_000002&quot;,</span>
<span class="go">      &quot;debugPort&quot;: 42071,</span>
<span class="go">      &quot;host&quot;: &quot;node-1004.my.cluster.net&quot;,</span>
<span class="go">      &quot;instance&quot;: 0,</span>
<span class="go">      &quot;memory&quot;: 512,</span>
<span class="go">      &quot;name&quot;: &quot;unique&quot;,</span>
<span class="go">      &quot;type&quot;: &quot;flowlet&quot;,</span>
<span class="go">      &quot;virtualCores&quot;: 1</span>
<span class="go">    },</span>
<span class="go">    ...</span>
<span class="go">    {</span>
<span class="go">      &quot;container&quot;: &quot;container_1397069870124_0010_01_000005&quot;,</span>
<span class="go">      &quot;debugPort&quot;: 37205,</span>
<span class="go">      &quot;host&quot;: &quot;node-1003.my.cluster.net&quot;,</span>
<span class="go">      &quot;instance&quot;: 0,</span>
<span class="go">      &quot;memory&quot;: 512,</span>
<span class="go">      &quot;name&quot;: &quot;splitter&quot;,</span>
<span class="go">      &quot;type&quot;: &quot;flowlet&quot;,</span>
<span class="go">      &quot;virtualCores&quot;: 1</span>
<span class="go">    }</span>
<span class="go">  ],</span>
<span class="go">  &quot;id&quot;: &quot;WordCounter&quot;,</span>
<span class="go">  &quot;runtime&quot;: &quot;distributed&quot;,</span>
<span class="go">  &quot;type&quot;: &quot;Flow&quot;,</span>
<span class="go">  &quot;yarnAppId&quot;: &quot;application_1397069870124_0010&quot;</span>
<span class="go">}</span>
</pre></div>
</div>
<p>You see the YARN application id and the YARN container IDs of each flowlet. More importantly, you
can see the host name and debugging port for each flowlet. For example, the only instance of the
<em>splitter</em> flowlet is running on <code class="docutils literal notranslate"><span class="pre">node-1003.my.cluster.net</span></code> and the debugging port is 37205. You can now
attach your debugger to the container’s JVM (see <a class="reference internal" href="#attaching-a-debugger">Attaching a Debugger</a>).</p>
<p>The corresponding HTTP requests for the <code class="docutils literal notranslate"><span class="pre">RetrieveCounts</span></code> service of this application would be:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">POST /v3/namespaces/default/apps/WordCount/services/RetrieveCounts/debug</span>
<span class="go">GET /v3/namespaces/default/apps/WordCount/services/RetrieveCounts/live-info</span>
</pre></div>
</div>
<p>Analysis of the response would give you the host names and debugging ports for all instances of the service.</p>
</div>
<div class="section" id="attaching-a-debugger">
<h2>Attaching a Debugger<a class="headerlink" href="#attaching-a-debugger" title="Permalink to this headline">🔗</a></h2>
<div class="section" id="debugging-with-intellij">
<h3>Debugging with IntelliJ<a class="headerlink" href="#debugging-with-intellij" title="Permalink to this headline">🔗</a></h3>
<p><em>Note:</em> These instructions were developed with <em>IntelliJ v13.1.2.</em>
You may need to adjust them for your installation or version.</p>
<ol class="arabic">
<li><p class="first">From the <em>IntelliJ</em> toolbar, select <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">-&gt;</span> <span class="pre">Edit</span> <span class="pre">Configurations</span></code>.</p>
</li>
<li><p class="first">Click <code class="docutils literal notranslate"><span class="pre">+</span></code> and choose <code class="docutils literal notranslate"><span class="pre">Remote</span></code>:</p>
<img alt="../_images/intellij_1.png" src="../_images/intellij_1.png" />
</li>
<li><p class="first">Create a debug configuration by entering a name, for example, <code class="docutils literal notranslate"><span class="pre">CDAP</span></code>.</p>
</li>
<li><p class="first">Enter the host name, for example, <code class="docutils literal notranslate"><span class="pre">localhost</span></code> or <code class="docutils literal notranslate"><span class="pre">node-1003.my.cluster.net</span></code>
in the Host field.</p>
</li>
<li><p class="first">Enter the debugging port, for example, <code class="docutils literal notranslate"><span class="pre">5005</span></code> in the Port field:</p>
<img alt="../_images/intellij_2.png" src="../_images/intellij_2.png" />
</li>
<li><p class="first">To start the debugger, select <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">-&gt;</span> <span class="pre">Debug</span> <span class="pre">-&gt;</span> <span class="pre">CDAP</span></code>.</p>
</li>
<li><p class="first">Set a breakpoint in any code block, for example, a flowlet method:</p>
<img alt="../_images/intellij_3.png" src="../_images/intellij_3.png" />
</li>
<li><p class="first">Start the flow in the CDAP UI.</p>
</li>
<li><p class="first">Send an event to the stream. The control will stop at the breakpoint
and you can proceed with debugging.</p>
</li>
</ol>
</div>
<div class="section" id="debugging-with-eclipse">
<h3>Debugging with Eclipse<a class="headerlink" href="#debugging-with-eclipse" title="Permalink to this headline">🔗</a></h3>
<p><em>Note:</em> These instructions were developed with <em>Eclipse IDE for Java Developers v4.4.0.</em>
You may need to adjust them for your installation or version.</p>
<ol class="arabic">
<li><p class="first">In Eclipse, select <code class="docutils literal notranslate"><span class="pre">Run-&gt;</span> <span class="pre">Debug</span></code> configurations.</p>
</li>
<li><p class="first">In the list on the left of the window, double-click <code class="docutils literal notranslate"><span class="pre">Remote</span> <span class="pre">Java</span> <span class="pre">Application</span></code> to create
a new launch configuration.</p>
<img alt="../_images/eclipse_1.png" src="../_images/eclipse_1.png" />
</li>
<li><p class="first">Enter a name and project, for example, <code class="docutils literal notranslate"><span class="pre">CDAP</span></code>.</p>
<img alt="../_images/eclipse_2.png" src="../_images/eclipse_2.png" />
</li>
<li><p class="first">Enter the host name, for example, <code class="docutils literal notranslate"><span class="pre">localhost</span></code> or <code class="docutils literal notranslate"><span class="pre">node-1003.my.cluster.net</span></code>
in the Host field.</p>
</li>
<li><p class="first">Enter the debugging port, for example, <code class="docutils literal notranslate"><span class="pre">5005</span></code> in the Port field.</p>
</li>
<li><p class="first">In your project, click <code class="docutils literal notranslate"><span class="pre">Debug</span></code> to start the debugger.</p>
</li>
<li><p class="first">Set a breakpoint in any code block, for example, a flowlet method:</p>
<img alt="../_images/eclipse_3.png" src="../_images/eclipse_3.png" />
</li>
<li><p class="first">Start the flow in the CDAP UI.</p>
</li>
<li><p class="first">Send an event to the stream.</p>
</li>
<li><p class="first">The control stops at the breakpoint and you can proceed with debugging.</p>
</li>
</ol>
</div>
</div>
<div class="section" id="debugging-the-transaction-manager-advanced-use">
<span id="tx-debugger"></span><h2>Debugging the Transaction Manager (Advanced Use)<a class="headerlink" href="#debugging-the-transaction-manager-advanced-use" title="Permalink to this headline">🔗</a></h2>
<p>In this advanced use section, we will explain in depth how transactions work internally.
Transactions are introduced in the <a class="reference internal" href="../building-blocks/transaction-system.html#transaction-system"><span class="std std-ref">Transaction System</span></a>.</p>
<p>A transaction is defined by an identifier, which contains the timestamp, in milliseconds,
of its creation. This identifier—also called the <cite>write pointer</cite>—represents the version
that this transaction will use for all of its writes. It is also used to determine
the order between transactions. A transaction with a smaller write pointer than
another transaction must have been started earlier.</p>
<p>The <cite>Transaction Manager</cite> (or TM) uses the write pointers to implement <cite>Optimistic Concurrency Control</cite>
by maintaining state for all transactions that could be facing concurrency issues.</p>
<div class="section" id="transaction-manager-states">
<h3>Transaction Manager States<a class="headerlink" href="#transaction-manager-states" title="Permalink to this headline">🔗</a></h3>
<p>The <cite>state</cite> of the TM is defined by these structures and rules:</p>
<ul class="simple">
<li>The <cite>in-progress set</cite>, which contains all the write pointers of transactions
which have neither committed nor aborted.</li>
<li>The <cite>invalid set</cite>, which contains the write pointers of the transactions
considered invalid, and which will never be committed. A transaction
becomes invalid only if either it times out or, for a long-running transaction,
it is being aborted.</li>
<li>A transaction’s write pointer cannot be in the <cite>in-progress set</cite>
and in the <cite>invalid set</cite> at the same time.</li>
<li>The <cite>invalid set</cite> and the <cite>in-progress set</cite> together form the <cite>excluded set</cite>.
When a transaction starts, a copy of this set is given to the transaction so that
it excludes from its reads any writes performed by transactions in that set.</li>
<li>The <cite>committing change sets</cite>, which maps write pointers of the transactions
which have requested to commit their writes and which have passed a first round of
conflict check to a list of keys in which they have performed those writes.</li>
<li>The <cite>committed change sets</cite>, which has the same structure as the <cite>committing change sets</cite>,
but where the write pointers refer to transactions which are already committed and
which have passed a second round of conflict check.</li>
</ul>
</div>
<div class="section" id="transaction-lifecycle-states">
<h3>Transaction Lifecycle States<a class="headerlink" href="#transaction-lifecycle-states" title="Permalink to this headline">🔗</a></h3>
<p>Here are the states a transaction goes through in its lifecycle:</p>
<ul class="simple">
<li>When a transaction starts, the TM creates a new write pointer
and saves it in the <cite>in-progress set</cite>.
A copy of the current excluded set is given to the transaction,
as well as a <cite>read pointer</cite>. The pointer
is an upper bound for the version of writes the transaction is allowed to read.
It prevents the transaction from reading committed writes performed after the transaction
started.</li>
<li>The transaction then performs writes to one or more rows, with the version of those writes
being the write pointer of the transaction.</li>
<li>When the transaction wants to commit its writes, it passes to the TM all the keys where
those writes took place. If the transaction is not in the <cite>excluded set</cite>, the
TM will use the <cite>committed change sets</cite> structure to detect
a conflict. A conflict happens in cases where the transaction tries to modify a
row which, after the start of the transaction, has been modified by one
of the transactions present in the structure.</li>
<li>If there are no conflicts, all the writes of the transaction along with its write pointer
are stored in the <cite>committing change sets</cite> structure.</li>
<li>The client—namely, a dataset—can then ask the TM to commit the writes. These are retrieved from the
<cite>committing change sets</cite> structure. Since the <cite>committed change sets</cite> structure might
have evolved since the last conflict check, another one is performed. If the
transaction is in the <cite>excluded set</cite>, the commit will fail regardless
of conflicts.</li>
<li>If the second conflict check finds no overlapping transactions, the transaction’s
write pointer is removed from the <cite>in-progress set</cite>, and it is placed in
the <cite>committed change sets</cite> structure, along with the keys it has
written to. The writes of this transaction will now be seen by all new transactions.</li>
<li>If something went wrong in one or other of the committing steps, we distinguish
between normal and long-running transactions:<ul>
<li>For a normal transaction, the cause could be that the transaction
was found in the excluded set or that a conflict was detected.
The client ensures rolling back the writes the transaction has made,
and it then asks the TM to abort the transaction.
This will remove the transaction’s write pointer from either the
<cite>in-progress set</cite> or the <cite>excluded set</cite>, and optionally from the
<cite>committing change sets</cite> structure.</li>
<li>For a long-running transaction, the only possible cause is that a conflict
was detected. Since it is assumed that the writes will not be rolled back
by the client, the TM aborts the transaction by storing its
write pointer into the <cite>excluded set</cite>. It is the only way to
make other transactions exclude the writes performed by this transaction.</li>
</ul>
</li>
</ul>
<p>The <cite>committed change sets</cite> structure determines how fast conflict detections
are performed. Fortunately, not all the committed writes need to be
remembered; only those which may create a conflict with in-progress
transactions. This is why only the writes committed after the start of the oldest,
in-progress, not-long-running transaction are stored in this structure,
and why transactions which participate in conflict detection must remain
short in duration. The older they are, the bigger the <cite>committed change sets</cite>
structure will be and the longer conflict detection will take.</p>
<p>When conflict detection takes longer, so does committing a transaction
and the transaction stays longer in the <cite>in-progress set</cite>. The whole transaction
system can become slow if such a situation occurs.</p>
</div>
<div class="section" id="dumping-the-transaction-manager">
<h3>Dumping the Transaction Manager<a class="headerlink" href="#dumping-the-transaction-manager" title="Permalink to this headline">🔗</a></h3>
<p>CDAP comes bundled with a script that allows you to dump the state of the internal
transaction manager into a local file to allow further investigation. If your CDAP Instance
tends to become slow, you can use this tool to detect the incriminating transactions.
This script is called <code class="docutils literal notranslate"><span class="pre">cdap</span> <span class="pre">debug</span> <span class="pre">transactions</span></code> (on Windows, it is <code class="docutils literal notranslate"><span class="pre">tx-debugger.bat</span></code>).</p>
<p>To download a snapshot of the state of the TM of the CDAP, use the command:</p>

<script type="text/javascript">

  $(function tabbedparsedliteral73() {
    var tabs = ['linux', 'windows'];
    var mapping = {'windows': 'windows', 'linux': 'linux'};
    var tabSetID = 'linux-windows';
    for (var i = 0; i < tabs.length; i++) {
      var tab = tabs[i];
      $("#tabbedparsedliteral73 .example-tab-" + tab).click(changeExampleTab(tab, mapping, "tabbedparsedliteral73", tabSetID));
    }
  });

</script>
<div id="tabbedparsedliteral73" class="tabbed-parsed-literal dependent-linux-windows">
<ul class="tabbed-parsed-literal nav-tabs">
<li class="example-tab example-tab-linux active"><a href="#">Linux</a></li>
<li class="example-tab example-tab-windows "><a href="#">Windows</a></li>
</ul>

<div class="tab-contents">

<div class="tab-pane tab-pane-linux active">
<div class="code code-tab">
<div class="highlight-console">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">$</span> cdap debug transactions view --host &lt;name&gt; <span class="o">[</span>--save &lt;filename&gt;<span class="o">]</span>
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
<div class="tab-pane tab-pane-windows ">
<div class="code code-tab">
<div class="highlight-shell-session">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">&gt;</span> tx-debugger.bat view --host &lt;name&gt; <span class="o">[</span>--save &lt;filename&gt;<span class="o">]</span>
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
</div>
</div>
<p>where <cite>name</cite> is the host name of your CDAP instance, and the optional <cite>filename</cite>
specifies where the snapshot should be saved. This command will
print statistics about all the structures that define the state of the TM.</p>
<p>You can also load a snapshot that has already been saved locally
with the command:</p>

<script type="text/javascript">

  $(function tabbedparsedliteral74() {
    var tabs = ['linux', 'windows'];
    var mapping = {'windows': 'windows', 'linux': 'linux'};
    var tabSetID = 'linux-windows';
    for (var i = 0; i < tabs.length; i++) {
      var tab = tabs[i];
      $("#tabbedparsedliteral74 .example-tab-" + tab).click(changeExampleTab(tab, mapping, "tabbedparsedliteral74", tabSetID));
    }
  });

</script>
<div id="tabbedparsedliteral74" class="tabbed-parsed-literal dependent-linux-windows">
<ul class="tabbed-parsed-literal nav-tabs">
<li class="example-tab example-tab-linux active"><a href="#">Linux</a></li>
<li class="example-tab example-tab-windows "><a href="#">Windows</a></li>
</ul>

<div class="tab-contents">

<div class="tab-pane tab-pane-linux active">
<div class="code code-tab">
<div class="highlight-console">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">$</span> cdap debug transactions view --filename &lt;filename&gt;
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
<div class="tab-pane tab-pane-windows ">
<div class="code code-tab">
<div class="highlight-shell-session">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">&gt;</span> tx-debugger.bat view --filename &lt;filename&gt;
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
</div>
</div>
<p>where <cite>filename</cite> specifies the location where the snapshot has been saved.</p>
<p>Here are options that you can use with the <code class="docutils literal notranslate"><span class="pre">tx-debugger</span> <span class="pre">view</span></code> commands:</p>
<ul class="simple">
<li>Use the <code class="docutils literal notranslate"><span class="pre">--ids</span></code> option to print all the transaction write pointers
that are stored in the different structures.</li>
<li>Use the <code class="docutils literal notranslate"><span class="pre">--transaction</span> <span class="pre">&lt;writePtr&gt;</span></code> option to specify the write pointer
of a transaction you would like information on. If the transaction is found
in the committing change sets or the committed change sets
structures, this will print the keys where the transaction has
performed writes.</li>
</ul>
<p>While transactions don’t inform you about the tasks that launched them—whether
it was a flowlet, a MapReduce program, etc.—you can match the time
they were started with the activity of your CDAP to track potential
issues.</p>
<p>If you really know what you are doing and you spot a transaction in the
in-progress set that should be in the excluded set, you can
use this command to invalidate it:</p>

<script type="text/javascript">

  $(function tabbedparsedliteral75() {
    var tabs = ['linux', 'windows'];
    var mapping = {'windows': 'windows', 'linux': 'linux'};
    var tabSetID = 'linux-windows';
    for (var i = 0; i < tabs.length; i++) {
      var tab = tabs[i];
      $("#tabbedparsedliteral75 .example-tab-" + tab).click(changeExampleTab(tab, mapping, "tabbedparsedliteral75", tabSetID));
    }
  });

</script>
<div id="tabbedparsedliteral75" class="tabbed-parsed-literal dependent-linux-windows">
<ul class="tabbed-parsed-literal nav-tabs">
<li class="example-tab example-tab-linux active"><a href="#">Linux</a></li>
<li class="example-tab example-tab-windows "><a href="#">Windows</a></li>
</ul>

<div class="tab-contents">

<div class="tab-pane tab-pane-linux active">
<div class="code code-tab">
<div class="highlight-console">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">$</span> cdap debug transactions invalidate --host &lt;name&gt; --transaction &lt;writePtr&gt;
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
<div class="tab-pane tab-pane-windows ">
<div class="code code-tab">
<div class="highlight-shell-session">
<!-- tabbed-parsed-literal start -->
<div class="highlight"><pre><span></span><span class="gp">&gt;</span> tx-debugger.bat invalidate --host &lt;name&gt; --transaction &lt;writePtr&gt;
</pre></div>
<!-- tabbed-parsed-literal end --></div>
</div>
</div>
</div>
</div>
<p>Invalidating a transaction when we know for sure that its writes should
be invalidated is useful, because those writes will then be removed
from the concerned Tables.</p>
</div>
</div>
</div>

</div>
    <div class="col-md-2">
      <div id="right-sidebar" class="bs-sidenav scrollable-y" role="complementary">
        <div id="localtoc-scrollspy">
        </div>
      </div>
    </div></div>
</div>
<!-- block main content end -->
<!-- block footer -->
<footer class="footer">
      <div class="container">
        <div class="row">
          <div class="col-md-2 footer-left"><a title="Testing a CDAP Application" href="testing.html" />Previous</a></div>
          <div class="col-md-8 footer-center"><a class="footer-tab-link" href="../table-of-contents/../../reference-manual/licenses/index.html">Copyright</a> &copy; 2014-2020 Cask Data, Inc.&bull; <a class="footer-tab-link" href="//docs.cask.co/cdap/6.1.1/cdap-docs-6.1.1-web.zip" rel="nofollow">Download</a> an archive or
<a class="footer-tab-link" href="//docs.cask.co/cdap">switch the version</a> of the documentation
          </div>
          <div class="col-md-2 footer-right"><a title="Troubleshooting a CDAP Application" href="troubleshooting.html" />Next</a></div>
        </div>
      </div>
    </footer>
<!-- block footer end -->
<script type="text/javascript" src="../_static/bootstrap-3.3.6/js/bootstrap.min.js"></script><script type="text/javascript" src="../_static/js/bootstrap-sphinx.js"></script><script type="text/javascript" src="../_static/js/abixTreeList-2.js"></script><script type="text/javascript" src="../_static/js/cdap-dynamicscrollspy-4.js"></script><script type="text/javascript" src="../_static/js/cdap-version-menu.js"></script><script type="text/javascript" src="../_static/js/copy-to-clipboard.js"></script><script type="text/javascript" src="../_static/js/jquery.mousewheel.min.js"></script><script type="text/javascript" src="../_static/js/jquery.mCustomScrollbar.js"></script><script type="text/javascript" src="../_static/js/js.cookie.js"></script><script type="text/javascript" src="../_static/js/tabbed-parsed-literal-0.2.js"></script><script type="text/javascript" src="../_static/js/cdap-onload-javascript.js"></script><script type="text/javascript" src="../_static/js/cdap-version-menu.js"></script>
    <script src="https://cdap.gitee.io/docs/cdap/json-versions.js"/></script>
  </body>
</html>